home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / ShowPages 1.4.1 / bbfig1.14 / bb.ps next >
Encoding:
Text File  |  1993-05-14  |  11.8 KB  |  580 lines  |  [TEXT/ttxt]

  1. %! 
  2. % bb.ps --
  3. % Prints a file, but keeps track of bounding box info, and prints the box at
  4. % the end (around the figure.)
  5. % $Header: bb.ps,v 1.14 91/03/21 13:04:02 cosell Exp $
  6. % RCS log info at end
  7.  
  8. 50 dict /$BoundingBox exch def
  9.  
  10. $BoundingBox begin
  11.  
  12. /xdef {
  13.     exch def
  14. } def
  15.  
  16. /xstore {
  17.     exch store
  18. } def
  19.  
  20. /addcoords {
  21.     exch
  22.     4 -1 roll add
  23.     3 1 roll add
  24. } def
  25.  
  26. % Stubs of old functions.
  27.  
  28. /-stroke /stroke load def
  29. /-fill /fill load def
  30. /-eofill /eofill load def
  31. /-image /image load def
  32. /-show /show load def
  33. /-awidthshow /awidthshow load def
  34. /-showpage /showpage load def
  35. /-restore  /restore load def
  36. /-imagemask /imagemask load def
  37.  
  38. end % $BoundingBox
  39.  
  40. % New Functions.   --- These go into the user dict to intercept the calls
  41.  
  42. /stroke {
  43.         $BoundingBox begin
  44.     gsave
  45.     initmatrix
  46.     (stroke called\n) traceprint %%DEBUG
  47.     {
  48.          strokepath    % Make sure to take line width into account.
  49.         0 setlinejoin
  50.         flattenpath
  51.     } stopped {        % strokepath often hits a limitcheck.
  52.         (Can't set up a strokepath\n) traceprint % DEBUG
  53.         grestore    % Restore the original path
  54.         gsave
  55.     } if
  56.     includepath            % Accumulate it into our box.
  57.     grestore
  58.  
  59.     -stroke
  60.     end % $BoundingBox
  61. } def
  62.  
  63. /fill {
  64.         $BoundingBox begin
  65.     gsave
  66.     (fill called\n) traceprint %%DEBUG
  67.     includepath
  68.     grestore
  69.  
  70.     -fill
  71.     end % $BoundingBox
  72. } def
  73.  
  74. /eofill {
  75.         $BoundingBox begin
  76.     gsave
  77.     (eofill called\n) traceprint %%DEBUG
  78.     includepath
  79.     grestore
  80.  
  81.     -eofill
  82.     end % $BoundingBox
  83. } def
  84.  
  85. % Text is implemented by reducing everything to an `awidthshow'.
  86.  
  87. /show {
  88.         $BoundingBox begin
  89.     (show called\n) traceprint %%DEBUG
  90.     0 0 0 0 0        % Extra parameters for awidthshow
  91.     6 -1 roll        % Bring the string back up
  92.     awidthshow
  93.     end % $BoundingBox
  94. } def
  95.  
  96. /widthshow {
  97.         $BoundingBox begin
  98.         (widthshow called\n) traceprint %%DEBUG
  99.     0 0            % Extra parameters for awidthshow
  100.     3 -1 roll        % Bring the string back up.
  101.     awidthshow
  102.     end % $BoundingBox
  103. } def
  104.  
  105. /ashow {
  106.         $BoundingBox begin
  107.         (ashow called\n) traceprint %%DEBUG
  108.     0 0 0 
  109.     6 3 roll
  110.     awidthshow
  111.     end % $BoundingBox
  112. } def
  113.  
  114.  
  115. % This does all of the work of the text-rendering operators
  116. %   What it does, is compute, basically brute force, what 'charpath'
  117. %   would have given us virtually for free, if 'show' were the only
  118. %   operator that we needed to do.
  119.  
  120. /awidthshow {
  121.     $BoundingBox begin
  122.     gsave
  123.     6 (awidthshow:) debug %%DEBUG
  124.     currentpoint
  125.     2 copy /@starty xdef /@startx xdef
  126.     2 index stringwidth    % Get the natural length of the string
  127.     addcoords            % Add to the start to get the end.
  128.  
  129.     2 index length        % How many characters?
  130.  
  131.     dup            % Add the offsets to each character
  132.     6 index mul
  133.     exch 5 index mul
  134.     addcoords
  135.  
  136.     5 index 3 index
  137.     chcount        % How many padding characters?
  138.  
  139.     dup            % Add the offsets for each pad.
  140.     9 index mul
  141.     exch 8 index mul
  142.     addcoords
  143.  
  144.     /@endy xdef /@endx xdef
  145.  
  146.     % We now have the left and right edges (in user coords)
  147.     % of the text.  Now we need only correct for the vertical
  148.     % displacements needed for the font and we can get the
  149.     % top and bottom edges of the enclosing box
  150.  
  151.     fontheight        % Get the height and depth of the current font.
  152.     
  153.     @startx @starty addcoords
  154.     /@starty xdef /@startx xdef
  155.     @endx @endy addcoords
  156.     /@endy xdef /@endx xdef
  157.     newpath
  158.     @startx @starty moveto
  159.     @endx @starty lineto
  160.     @endx @endy lineto
  161.     @startx @endy lineto
  162.     closepath
  163.         includepath
  164.     grestore
  165.  
  166.     -awidthshow
  167.     end % $BoundingBox
  168. } def
  169.  
  170. % `image':
  171. % Assume here that the image lands in the unit square.
  172.  
  173. /image {
  174.         $BoundingBox begin
  175.         (image called\n) traceprint %%DEBUG
  176.     gsave
  177.     newpath
  178.     0 0 moveto
  179.     1 0 rlineto
  180.     1 1 rlineto
  181.     -1 0 rlineto
  182.     closepath
  183.     includepath
  184.     grestore
  185.  
  186.     -image
  187.     end % $BoundingBox
  188. } def
  189.  
  190. /imagemask
  191. {
  192.     $BoundingBox begin
  193.     (imagemask called\n) traceprint %%DEBUG
  194.     gsave
  195.     newpath
  196.     0 0 moveto
  197.     1 0 rlineto
  198.     1 1 rlineto
  199.     -1 0 rlineto
  200.     closepath
  201.     includepath
  202.     grestore
  203.  
  204.     -imagemask
  205.     end % $BoundingBox
  206. } def
  207.  
  208. % Just define this one out of existence
  209. /framedevice { pop pop pop pop } def
  210.  
  211. % Handle restoring VM --- this is all OK, except that we have to
  212. % hang onto the bb info we collected while in the about-to-be-discarded
  213. % environment
  214.  
  215. /restore
  216. {
  217.     $BoundingBox begin
  218.     (restore called\n) traceprint %%DEBUG
  219.     tracedump  %% HACK, but the only way I see right now to get this stuff!
  220.     bbox-llx bbox-lly bbox-urx bbox-ury 
  221.     5 -1 roll
  222.     -restore
  223.     /bbox-ury xstore /bbox-urx xstore
  224.     /bbox-lly xstore /bbox-llx xstore
  225.     end % $BoundingBox
  226. } def
  227.  
  228.     
  229. % `showpage':
  230. % Just draw the box around the figure and print the page, and then initialize
  231. % the bounding box variables again.
  232.  
  233. $BoundingBox begin
  234. /temp-string 10 string def
  235. end % $BoundingBox
  236.  
  237. /showpage {
  238.     $BoundingBox begin
  239.     initgraphics
  240.  
  241.         (showpage\n) traceprint % DEBUG
  242.     dump-bbox  % DEBUG
  243.  
  244.         /bbox-llx round_down
  245.     /bbox-lly round_down
  246.     /bbox-ury round_up
  247.     /bbox-urx round_up
  248.  
  249.     bbox-llx bbox-lly moveto        % Make the box
  250.     bbox-llx bbox-ury lineto
  251.     bbox-urx bbox-ury lineto
  252.     bbox-urx bbox-lly lineto
  253.     closepath
  254.  
  255.     bwstroke            % Draw the box.
  256.  
  257. % Print the size of the bounding box both above and below the actual box
  258.     0 setgray
  259.     /Courier findfont 10 scalefont setfont
  260.     bbox-llx 36 max bbox-lly 12 sub 36 max moveto
  261.     (%%BoundingBox: ) -show
  262.     bbox-llx temp-string cvs -show ( ) -show
  263.     bbox-lly temp-string cvs -show ( ) -show
  264.     bbox-urx temp-string cvs -show ( ) -show
  265.     bbox-ury temp-string cvs -show
  266.  
  267.     bbox-llx 36 max bbox-ury 12 add 740 min moveto
  268.     (%%BoundingBox: ) -show
  269.     bbox-llx temp-string cvs -show ( ) -show
  270.     bbox-lly temp-string cvs -show ( ) -show
  271.     bbox-urx temp-string cvs -show ( ) -show
  272.     bbox-ury temp-string cvs -show
  273.  
  274.     init
  275.     -showpage
  276.     tracedump        %% DEBUG
  277.     end % $BoundingBox
  278. } def
  279.  
  280. % BoundingBox functions:
  281. % We accumulate the information about the bounding box into four variables.
  282. % The data is stored in default coordinates.
  283.  
  284. $BoundingBox begin
  285.  
  286. /init {
  287.     /bbox-llx 99999 store
  288.     /bbox-lly 99999 store
  289.     /bbox-urx -99999 store
  290.     /bbox-ury -99999 store
  291. } def
  292.  
  293. /bbox-llx 0 def
  294. /bbox-lly 0 def
  295. /bbox-urx 0 def
  296. /bbox-ury 0 def
  297.  
  298. % - `includepath' -
  299. % Incorporates the bounding box of the path into the bounding box info.
  300. %   ... Gets the bounding box in default coords
  301.  
  302. /includepath {
  303.         (Adding a path: ) traceprint %%DEBUG
  304.     gsave
  305.         initmatrix
  306.     {
  307.         0 setlinejoin
  308.         flattenpath
  309.     } stopped {
  310.         (Couldn't flatten the path\n) traceprint % DEBUG
  311.         grestore
  312.         gsave
  313.         initmatrix
  314.     } if
  315.     { pathbbox } stopped not
  316.     {
  317.             4 2 roll    % Just so we get lower-left first
  318.         2 copy dump-coord %%DEBUG
  319.         dup bbox-lly lt {    
  320.             /bbox-lly xstore
  321.         } {
  322.             pop
  323.         } ifelse
  324.         dup bbox-llx lt {
  325.             /bbox-llx xstore
  326.         } {
  327.             pop
  328.         } ifelse
  329.  
  330.         (; ) traceprint 2 copy dump-coord (\n) traceprint %%DEBUG
  331.         dup bbox-ury gt {
  332.             /bbox-ury xstore
  333.         } {
  334.             pop
  335.         } ifelse
  336.         dup bbox-urx gt {
  337.             /bbox-urx xstore
  338.         } {
  339.             pop
  340.         } ifelse
  341.         dump-bbox  %%DEBUG
  342.     } if
  343.     grestore
  344. } def
  345.  
  346. % A nice black-and white line drawing function.
  347.  
  348. /bwstroke {
  349.     0 setlinewidth            % Thinnest possible lines
  350.     1 setgray            % White first
  351.     [5] 0 setdash            % Only half the line
  352.     gsave -stroke grestore
  353.     0 setgray            % Then black
  354.     [5] 5 setdash            % On the other half
  355.     -stroke
  356. } def
  357.  
  358. % Stuff for text.
  359.  
  360. % char-code string `chcount' occurs
  361. % Counts the number of times a character appears in a string.
  362.  
  363. /chcount {
  364.     0 exch
  365.     {
  366.         2 index eq {
  367.             1 add
  368.         } if
  369.     } forall
  370.     exch pop
  371. } def
  372.  
  373. % - `fontheight' heightx heighty depthx depthy
  374. % Returns the offsets to the lowest point and highest point in the current
  375. % font.
  376.  
  377. /fontheight {
  378.     currentfont begin
  379.     /FontBBox load aload pop
  380.     exch pop 0 exch
  381.     FontMatrix transform
  382.     4 2 roll
  383.     exch pop 0 exch
  384.     FontMatrix transform
  385.     end
  386. } def
  387.  
  388. % key round_{down|up} -  These will round the value of the given key
  389. %                         up or down, as appropriate, to the nearest integer
  390. /round_up   { dup load ceiling cvi store } def
  391. /round_down { dup load floor   cvi store } def
  392.  
  393. % key binddefinition - this will do a 'bind' on the procedure given by 'key'
  394. /binddefinition
  395. {
  396.     dup where
  397.     {  
  398.         exch
  399.         2 copy
  400.         get bind put
  401.     }     
  402.     { undefined } ifelse
  403. } def  
  404.  
  405. % Given two numbers on the stack, return with just the smallest
  406. /min { 2 copy ge { exch } if pop } def
  407.  
  408. % Dito for the largest of the pair
  409. /max { 2 copy lt { exch } if pop } def
  410.  
  411.  
  412. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
  413. %
  414. %   Debugging utilities
  415. %
  416.  
  417. /$tracedict where
  418. {  % Trace package loaded... do the tracing
  419.     pop
  420. % This is a debugging function to print out what is going on.
  421. %  Format <argn> <argn-1> ... <arg1> n <string> debug <argn> ... <arg1>
  422. %    (that is, the 'n' args will be *left* on the stack!)
  423. /debug
  424. {
  425.     traceprint (\n) traceprint 
  426.     dup 1 add   % Now total number of args (including arg count) 
  427.     copy
  428.     {
  429.         (    ) traceprint 
  430.     trace=
  431.         (\n) traceprint
  432.     } repeat
  433.     pop    % Remove the extra copy of the arg count
  434. } def
  435.  
  436. % Print out a coordinate on the stack:  x y --- 
  437. /dump-coord
  438. {
  439.     (\() traceprint exch trace= (, ) traceprint trace= (\)) traceprint
  440. } def
  441.  
  442. % Print out bb's current notion of its bounding box
  443.  
  444. /dump-bbox
  445. {
  446.     (Bounding Box: ) traceprint
  447.     bbox-llx bbox-lly dump-coord
  448.     (; ) traceprint
  449.     bbox-urx bbox-ury dump-coord
  450.     (\n) traceprint
  451. } def
  452.  
  453. tracebegin %% DEBUG
  454.  
  455. }
  456. { % No trace package loaded, so don't trace.  Stub out the various calls
  457.  
  458. /traceprint { pop } def
  459. /dump-coord { pop pop } def
  460. /dump-bbox { } def
  461. /debug { pop  pop } def
  462. /tracedump { } def
  463.  
  464. } ifelse
  465.  
  466. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
  467.  
  468. % Bind everything
  469.  
  470. /xdef binddefinition
  471. /xstore binddefinition
  472. /addcoords binddefinition
  473. /stroke binddefinition
  474. /fill binddefinition
  475. /eofill binddefinition
  476. /show binddefinition
  477. /widthshow binddefinition
  478. /ashow binddefinition
  479. /awidthshow binddefinition
  480. /image binddefinition
  481. /showpage binddefinition
  482. /init binddefinition
  483. /includepath binddefinition
  484. /bwstroke binddefinition
  485. /chcount binddefinition
  486. /fontheight binddefinition
  487.  
  488. /debug binddefinition
  489. /dump-coord binddefinition
  490. /dump-bbox binddefinition
  491.  
  492. % Start it up.
  493.  
  494. init
  495.  
  496. end % $BoundingBox
  497.  
  498. %  end of bb.ps
  499.  
  500. % $Log:    bb.ps,v $
  501. % Revision 1.14  91/03/21  13:04:02  cosell
  502. % Relocated the position of the constrained BBox info
  503. % Revision 1.13  91/03/21  12:21:04  cosell
  504. % Forced the %BoundingBox info to stay within the page boundaries
  505. % Revision 1.12  91/03/21  12:15:17  cosell
  506. % Added a tracing hook to bridge restores.
  507. % Revision 1.11  90/07/02  08:48:40  cosell
  508. % bbfig now correctly copes with empty paths
  509. % Revision 1.10  90/06/27  10:47:22  cosell
  510. % Added a bunch of improvements from Joe Pallas at stanford.
  511. % Revision 1.9  90/06/26  10:50:20  cosell
  512. % Stack got botched in the 'debug' stub
  513. % Revision 1.8  90/06/25  09:34:51  cosell
  514. % Minor bug in 'restore'
  515. % Revision 1.7  90/06/25  09:29:58  cosell
  516. % Added code to catch and deal with 'restore'.  Thanks to Frank
  517. % Jensen for finding this one
  518. % Revision 1.6  90/06/25  09:23:26  cosell
  519. % Small bugfix in the text-handling stuff
  520. % Revision 1.5  90/06/10  09:04:02  cosell
  521. % Changed the printed string to explictly say "%%BoundingBox"
  522. % Revision 1.4  90/06/10  08:55:39  cosell
  523. % Added 'bind' machinery to insulate this package from later redefinitions
  524. % of things we need from the systemdict.
  525. % Revision 1.3  90/06/10  08:28:53  cosell
  526. % Added debugging hooks.  They don't affect anything (and don't do
  527. % anything) in the normal use of bbfig.  But if the 'trace' package
  528. % is loaded ahead of this, it'll print out some helpful info.  Probably
  529. % I'll end up removing all of this if/when I really get the package
  530. % up to snuff.
  531. % Revision 1.2  90/05/25  12:08:24  cosell
  532. % Major improvements and tuneups:  fixed it to really use its private
  533. % discionary, and the most importnat: it now computes the bounding box
  534. % in *default* coords
  535. %
  536. % Revision 1.1  90/05/23  08:18:54  cosell
  537. % Initial revision
  538. %   This is Ned Bachelder's original version
  539.